package com.beidouin.GnssMain.models;

import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.util.Log;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;

/**
 * Created by flyingfluff on 2016/9/26.
 */

public class GnssData {
    public static final int Status_Not_Fixed = 0;
    public static final int Status_Fixed = 1;

    private static GnssData sInstance;
    private static HashMap<String, String> locateTypeMap = new HashMap<String, String>();

    private int fixStatus = 0;  //0: not positioned, 1: positioned
    private Date date = new Date();
    private double latitude = 0;
    private double longitude = 0;
    private double altitude = 0;
    private double speed = 0;
    private double direction = 0;
    private double pdop = 0;
    private int nSatellitesRecv = 0;
    private int nSatellitesUsed = 0;
    private int nSatellitesMax = 0;
    private GnssSatellite[] satellites;
    private GnssSatellite[][] satellitesNmea;

    public static GnssData getInstance() {
        if (sInstance == null)
            sInstance = new GnssData();
        return sInstance;
    }


    public static void init() {
        sInstance = new GnssData();

        locateTypeMap.put("0", "0 未定位");
        locateTypeMap.put("1", "1 单点定位");
        locateTypeMap.put("2", "2 伪距差分");
        locateTypeMap.put("4", "4 RTK固定解");
        locateTypeMap.put("5", "5 RTK浮点解");
        locateTypeMap.put("6", "6 正在估算");
    }

    public void setFixStatus(int status) {fixStatus = status; }
    public void setDateTime(Date d) { date = d; }
    public void setLatitude(double lat) { latitude = lat; }
    public void setLongitude(double lon) { longitude = lon; }
    public void setAltitude(double alt) { altitude = alt; }
    public void setSpeed(double spd) { speed = spd; }
    public void setDirection(double dir) { direction = dir; }
    public void setPdop(double dop) { pdop = dop; }
    public void setSatellitesRecv(int n) { nSatellitesRecv = n; }
    public void setSatellitesUsed(int n) { nSatellitesUsed = n; }
    public void setSatellitesMax(int n) { nSatellitesMax = n; }

    public void setGnssSatellite(GpsStatus status) {

        Log.e("hasjsajsasa","==============================获取卫星最大值222222222222.。。。。。。。。。。。。。222222   请求更新=====");

        try {
            nSatellitesMax = status.getMaxSatellites();


            Iterator<GpsSatellite> iters = status.getSatellites()
                    .iterator();
            int count = 0;
            while (iters.hasNext() && count <= nSatellitesMax) {
                iters.next();
                count++;
            }

            nSatellitesRecv = count;
            iters = status.getSatellites().iterator();
            satellites = new GnssSatellite[nSatellitesMax];
            GnssSatellite tempSate;
            int nUsed = 0;
            count = 0;
            fixStatus = Status_Not_Fixed;
            while (iters.hasNext() && count <= nSatellitesMax) {
                if (count > satellites.length) {
                    break;
                }
                tempSate = GnssSatellite.copyValue(iters.next());
                if (tempSate.getType() != GnssSatellite.SATE_BEIDOU)
                    continue;
                satellites[count] = tempSate;
                if (satellites[count].isUsedInFix()) {
                    fixStatus = Status_Fixed;
                    ++nUsed;
                }
                count++;
            }
            //再加入其他卫星
            iters = status.getSatellites().iterator();
            while (iters.hasNext() && count <= nSatellitesMax) {
                if (count > satellites.length) {
                    break;
                }
                tempSate = GnssSatellite.copyValue(iters.next());
                if (tempSate.getType() == GnssSatellite.SATE_BEIDOU)
                    continue;
                satellites[count] = tempSate;
                if (satellites[count].isUsedInFix()) {
                    fixStatus = Status_Fixed;
                    ++nUsed;
                }
                count++;
            }
            for(int i = count; i < satellites.length; ++i) {
                satellites[i] = null;
            }
            nSatellitesRecv = count;
            nSatellitesUsed = nUsed;
        }catch (Exception e)
        {
            System.out.println("Catch a exception in GnssData:setGnssSatellite");
        }
        return;
    }

    public void setGnssSatellite(GnssSatellite[][] sate) {
        satellitesNmea = sate;
    }

    //public Date getDateTime() { return date; }
    public int getFixStatus() { return fixStatus; }
    public double getLatitude() { return latitude; }
    public double getLongitude() { return longitude; }
    public double getAltitude() { return altitude; }
    public double getSpeed() { return speed; }
    public double getDirection() { return direction; }
    public double getPdop() { return pdop; }
    public int getSatellitesRecv() { return nSatellitesRecv; }
    public int getSatellitesUsed() { return nSatellitesUsed; }
    public int getSatellitesMax() { return nSatellitesMax; }
    public GnssSatellite[] getSatellites() { return satellites; }
    public GnssSatellite[][] getSatellitesNmea() { return satellitesNmea; }

    public String getGMT8Time() {
        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return formatter.format(date.getTime());
    }
    public String getGMT8Date() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return formatter.format(date.getTime());
    }

    public String getGMTTime() {
        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
        return formatter.format(date.getTime());
    }

    public String getGMTDate() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
        return formatter.format(date.getTime());
    }

    public String transLat(int level, String type, boolean bPlusMinus){
        String ret = "";
        int iDegree, iMinute;
        double value, dMinute, dSecond;
        String tail = "";
        boolean bPositive = true;
        try{
            if(type.equals("latitude")){
                value = latitude;
                tail = "N";
            }else{
                value = longitude;
                tail = "E";
            }

            if (value < 0) {
                bPositive = false;
                value = - value;
                if (type.equals("latitude"))
                    tail = "S";
                else
                    tail = "W";
            }


            if(level == 0){ //度
                ret = String.format("%.8f°", value);
            }else if(level == 1){ //度分
                iDegree = (int)value;
                dMinute = (value - iDegree) * 60;
                ret = String.format("%d°%.6f'", iDegree, dMinute);
            }else{ //度分秒
                iDegree = (int)value;
                dMinute = (value - iDegree) * 60;
                iMinute = (int)dMinute;
                dSecond = (dMinute - iMinute) * 60;
                ret = String.format("%d°%d'%.4f\"", iDegree, iMinute, dSecond);
            }
            if (bPlusMinus && bPositive == false)
                ret = "-" + ret;
            else if (bPlusMinus == false)
                ret = ret + tail;
            return ret;
        }catch (Exception e){
            System.out.println("exception=" + latitude +" " + longitude);
            if(type.equals("latitude")){
                return String.valueOf(latitude);
            }else{
                return String.valueOf(longitude);
            }
        }
    }

    public int[][] getSatelliteNumber() {
        int[][] num = new int[GnssSatellite.SATE_TOTAL + 1][2]; //0 for used, 1 for received

        //from NMEA
        if (SysParam.getDataSource() == SysParam.FROM_NMEA) {
            for (int i = 0; i < GnssSatellite.SATE_TOTAL; ++i) {
                if (satellitesNmea == null || satellitesNmea[i] == null) {
                    continue;
                }

                for (int j = 0; j < satellitesNmea[i].length; ++j) {
                    if (satellitesNmea[i][j].getSnr() != 0)
                        ++num[i][1];
                    if (satellitesNmea[i][j].isUsedInFix())
                        ++num[i][0];
                }
                num[GnssSatellite.SATE_TOTAL][0] += num[i][0];
                num[GnssSatellite.SATE_TOTAL][1] += num[i][1];
            }
            return num;
        } else {
            //from driver
            if (satellites == null)
                return null;
            for (int i = 0; i < satellites.length; ++i) {
                if (satellites[i] == null)
                    continue;
                int type = satellites[i].getType();
                if (satellites[i].getSnr() != 0)
                    ++num[type][1];
                if (satellites[i].isUsedInFix())
                    ++num[type][0];
            }
            for (int i = 0; i <= GnssSatellite.SATE_OTHER; ++i) {
                num[GnssSatellite.SATE_TOTAL][0] += num[i][0];
                num[GnssSatellite.SATE_TOTAL][1] += num[i][1];
            }
            return num;
        }
    }

    public List<GnssSatellite> getSatellitesList(){
        if (nSatellitesRecv > 0) {
            return Arrays.asList(satellites);
        } else {
            return null;
        }
    }
}
